iT邦幫忙

2026 iThome 鐵人賽

DAY 26
0
IT Operation

Docker 新手村:從容器到 PostgreSQL 的實戰之路系列 第 27 篇

Day 26 - 環境變數與 .env:不要把資料庫密碼寫死在程式裡

  • 分享至 

  • xImage
  •  

學習目標

  • 了解為什麼不應該把帳號密碼直接寫在程式碼中
  • 認識 .env 環境變數檔案
  • 使用 Node.js 讀取環境變數
  • 將 PostgreSQL 連線資訊移出程式碼
  • 了解 .gitignore 的用途

目前的問題

Day 25 已經成功讓 Node.js Container 透過 Docker Network 連線 PostgreSQL。

但目前程式中還有一個問題:

const client = new Client({
  host: "postgres",
  port: 5432,
  user: "myuser",
  password: "123456",
  database: "schedule_db"
});

資料庫帳號、密碼和 Database 名稱全部直接寫在程式碼裡。

練習時看起來沒有什麼問題,但如果程式上傳到 GitHub,就可能不小心把真正的帳號密碼一起公開。

因此今天要把這些設定移到 .env。


什麼是 .env?

.env 是常見的環境變數設定檔,可以將一些容易變動或不適合直接寫在程式中的設定獨立保存。

例如:

DB_HOST=postgres
DB_PORT=5432
DB_USER=myuser
DB_PASSWORD=123456
DB_NAME=schedule_db

之後程式就不需要直接出現真正的資料庫密碼。

整體概念變成:

.env
 │
 │ 讀取設定
 ↓
Node.js
 │
 ↓
PostgreSQL

安裝 dotenv

如果 Node.js 專案需要從 .env 檔案讀取變數,可以安裝 dotenv:

npm install dotenv

接著在 app.js 最上方加入:

require("dotenv").config();

這樣程式就可以透過:

process.env

取得環境變數。


修改 PostgreSQL 連線設定

原本的程式:

const client = new Client({
  host: "postgres",
  port: 5432,
  user: "myuser",
  password: "123456",
  database: "schedule_db"
});

可以修改成:

require("dotenv").config();

const { Client } = require("pg");

const client = new Client({
  host: process.env.DB_HOST,
  port: Number(process.env.DB_PORT),
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME
});

現在程式只負責讀取設定,不需要知道真正的密碼是多少。


Docker Compose 使用 .env

Docker Compose 也可以使用 .env 中的變數。

例如 .env:

POSTGRES_USER=myuser
POSTGRES_PASSWORD=123456
POSTGRES_DB=schedule_db

DB_HOST=postgres
DB_PORT=5432
DB_USER=myuser
DB_PASSWORD=123456
DB_NAME=schedule_db

接著修改 compose.yml:

services:
  postgres:
    image: postgres:17
    container_name: my-postgres
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    ports:
      - "5432:5432"
    volumes:
      - postgres-data:/var/lib/postgresql/data

  app:
    build: .
    container_name: my-node-app
    env_file:
      - .env
    depends_on:
      - postgres

volumes:
  postgres-data:

這樣 Compose 和 Node.js 都可以從環境變數取得需要的設定。


記得加入 .gitignore

雖然帳號密碼已經移到 .env,但如果最後又把 .env 上傳到 GitHub,那就失去原本的意義了。

因此可以建立:

.gitignore

加入:

.env
node_modules/

這樣 Git 就會忽略 .env。

可以另外建立一份:

.env.example

內容只保留變數名稱:

DB_HOST=
DB_PORT=
DB_USER=
DB_PASSWORD=
DB_NAME=

這樣其他人可以知道專案需要哪些設定,又不會看到真正的密碼。


再次啟動服務

修改完成後,可以重新 Build:

docker compose down

再執行:

docker compose up -d --build

查看服務:

docker compose ps

如果想確認 Node.js 是否成功連線:

docker compose logs app

成功的話,就代表 Node.js 已經透過環境變數取得 PostgreSQL 的連線資訊。


今天的架構

現在整個設定方式變成:

.env
 │
 ├── DB_HOST
 ├── DB_USER
 ├── DB_PASSWORD
 └── DB_NAME
       │
       ↓
    Node.js
       │
       ↓
   postgres:5432
       │
       ↓
  PostgreSQL

和直接把密碼寫在 app.js 相比,設定與程式碼也被分開管理。


常見錯誤與修正

  • ❌ 把資料庫密碼直接寫在程式碼 → ✅ 改用環境變數
  • ❌ 忘記執行 npm install dotenv → ✅ 安裝後再使用 require("dotenv").config()
  • ❌ process.env 讀不到資料 → ✅ 確認 .env 位置與變數名稱
  • ❌ .env 被上傳到 Git → ✅ 將 .env 加入 .gitignore
  • ❌ 修改 .env 後 Container 還是舊設定 → ✅ 重新建立 Container
  • ❌ 把 .env.example 也放入真密碼 → ✅ 範例檔只保留變數名稱或示意值

今日小挑戰(可交付)

  • [ ] 建立 .env
  • [ ] 將 PostgreSQL 帳號密碼移到 .env
  • [ ] 安裝 dotenv
  • [ ] 使用 process.env 讀取資料
  • [ ] 修改 compose.yml 使用環境變數
  • [ ] 將 .env 加入 .gitignore
  • [ ] 建立 .env.example
  • [ ] 重新啟動後成功連線 PostgreSQL

DAY26 心得

今天把原本直接寫在 Node.js 程式裡面的 PostgreSQL 帳號和密碼移到 .env,也開始理解為什麼實際開發時會把程式碼和環境設定分開。

以前看到 .env 和 process.env 時,只知道它們好像跟帳號密碼有關,但實際放進 Docker Compose 和 Node.js 後,才比較清楚整個使用方式。

尤其是 .gitignore 也很重要,如果只是把密碼移到 .env,最後卻還是把 .env 上傳到 GitHub,那就沒有真正保護到這些資訊。現在整個環境已經比較接近真正專案的做法,下一步就可以開始設計員工與排班需要使用的資料表。


上一篇
Day 25 - Docker Network 實戰:讓 Node.js 與 PostgreSQL 互相溝通
下一篇
Day 27 - 設計員工與排班資料表:把專題資料放進 PostgreSQL
系列文
Docker 新手村:從容器到 PostgreSQL 的實戰之路 共 31 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言